//
//  ViewController.m
//  FlutteriOS
//
//  Created by tikeyc on 2023/6/7.
//

#import "ViewController.h"

#import "AppDelegate.h"
#import <AVFAudio/AVFAudio.h>

@interface ViewController ()<FlutterStreamHandler> {
    int _lastVolume;
}

@property(nonatomic, copy)FlutterEventSink eventSink;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self addVolumeKVC];
}

- (IBAction)gotoFlutterVC:(UIButton *)sender {
    switch (sender.tag) {
        case 1:
            [self showFlutter1];
            break;
        case 2:
            [self showFlutter2];
            break;
            
        default:
            break;
    }
}


- (void)showFlutter1 {
    FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil];
    //
    [self initFlutterMethodChannel:flutterViewController];
    [self initFlutterBasicMessageChannel:flutterViewController];
    [self initFlutterEventChannel: flutterViewController];
    
    [self presentViewController:flutterViewController animated:YES completion:nil];
}


- (void)showFlutter2 {
    FlutterEngine *flutterEngine =
        ((AppDelegate *)UIApplication.sharedApplication.delegate).flutterEngine;
    
    FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
//    [flutterViewController setInitialRoute:@"/"];
//    [flutterEngine runWithEntrypoint:FlutterDefaultDartEntrypoint initialRoute:@"/"];
    
    
//    FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithProject:nil initialRoute:@"/" nibName:nil bundle:nil];
    //
    [self initFlutterMethodChannel:flutterViewController];
//    [self initFlutterBasicMessageChannel:flutterViewController];
    [self initFlutterEventChannel: flutterViewController];
    
    [self presentViewController:flutterViewController animated:YES completion:nil];
}

#pragma mark -

- (void)initFlutterMethodChannel:(FlutterViewController *)flutterViewController {
    NSString *name = @"com.tikeyc.fluttermodule/methodChannel";
    FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:name binaryMessenger:flutterViewController.binaryMessenger];
    [methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
        if ([call.method isEqualToString:@"testMethodCall"]) {
            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示信息" message:call.arguments preferredStyle:UIAlertControllerStyleAlert];
            [self presentViewController:alertController animated:YES completion:^{
                
            }];
            result(@"原生返回给flutter的信息");
        }
    }];
//    [methodChannel invokeMethod:@"" arguments:@{} result:^(id  _Nullable result) {
//
//    }];
//    [methodChannel invokeMethod:@"" arguments:@{}];
}

- (void)initFlutterBasicMessageChannel:(FlutterViewController *)flutterViewController {
    NSString *name = @"com.tikeyc.fluttermodule/basicMethodChannel";
    FlutterBasicMessageChannel *basicMessageChannel = [FlutterBasicMessageChannel messageChannelWithName:name binaryMessenger:flutterViewController.binaryMessenger];
    [basicMessageChannel setMessageHandler:^(id  _Nullable message, FlutterReply  _Nonnull callback) {
        NSLog(@"收到了Flutter端发来的消息:%@", message);
        callback(@"iOS tikeyc");
    }];
    //
//    [basicMessageChannel sendMessage:<#(id _Nullable)#>];
    [basicMessageChannel sendMessage:@"Hello, this is BasicMethodChannel Send msg!" reply:^(id  _Nullable reply) {
        NSLog(@"收到了Flutter端发来的回复：:%@", reply);
    }];
}

- (void)initFlutterEventChannel:(FlutterViewController *)flutterViewController {
    NSString *name = @"com.tikeyc.fluttermodule/eventChannel";
    FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:name binaryMessenger:flutterViewController.binaryMessenger];
    [eventChannel setStreamHandler:self];
}

#pragma mark - FlutterStreamHandler

/**
 * Sets up an event stream and begin emitting events.
 *
 * Invoked when the first listener is registered with the Stream associated to
 * this channel on the Flutter side.
 *
 * @param arguments Arguments for the stream.
 * @param events A callback to asynchronously emit events. Invoke the
 *     callback with a `FlutterError` to emit an error event. Invoke the
 *     callback with `FlutterEndOfEventStream` to indicate that no more
 *     events will be emitted. Any other value, including `nil` are emitted as,
 *     successful events.
 * @return A FlutterError instance, if setup fails.
 */
- (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments
                                       eventSink:(FlutterEventSink)events {
    self.eventSink = events;
    return nil;
}

/**
 * Tears down an event stream.
 *
 * Invoked when the last listener is deregistered from the Stream associated to
 * this channel on the Flutter side.
 *
 * The channel implementation may call this method with `nil` arguments
 * to separate a pair of two consecutive set up requests. Such request pairs
 * may occur during Flutter hot restart.
 *
 * @param arguments Arguments for the stream.
 * @return A FlutterError instance, if teardown fails.
 */
- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {
    self.eventSink = nil;
    return nil;
}

-(void)dealloc {
    [self removeVolumeKVC];
}

#pragma mark - addVolumeNotification
- (void)removeVolumeKVC {
    [UIApplication.sharedApplication endReceivingRemoteControlEvents];
    [AVAudioSession.sharedInstance removeObserver:self forKeyPath:@"outputVolume" context:nil];
}

- (void)addVolumeKVC {
    _lastVolume = [AVAudioSession.sharedInstance outputVolume];
    //
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setActive:YES error:nil];
    [session addObserver:self forKeyPath:@"outputVolume" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqual:@"outputVolume"]) {
        NSLog(@"%@", change);
        if (self.eventSink) {
            int volume = [[change objectForKey:@"volume"] intValue];
            self.eventSink(@{
                @"type": @"changeVolume",
                @"currentVolume": @(volume),
                @"des": volume > _lastVolume ? @"音量键up" : @"音量键down",
            });
        }
    }
}

@end
